package org.folio.rest.impl.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import org.folio.cql2pgjson.exception.FieldException;
import org.folio.rest.impl.other.PartyUtil;
import org.folio.rest.jaxrs.model.*;
import org.folio.rest.persist.PostgresClient;
import org.folio.rest.persist.cql.CQLWrapper;

import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author lee
 * @Classname ReaderChangeReserve
 * @Description TODO
 * @Date 2020/7/8 14:11
 * @Created by lee
 */
public class ReaderChangeReserve {

    public static void change(ReaderReserveChangeRequest entity, PostgresClient pg, Handler<AsyncResult<ReaderReserveChangeResponse>> asyncResultHandler) {
        Future<ReaderReserveChangeResponse> future = Future.future();
        Attend attend = new Attend();
        ReaderReserveChangeResponse response = new ReaderReserveChangeResponse();

        pg.getById("party", entity.getPartyId(), Party.class, reply -> {
            if (reply.succeeded()) {
                Party party = reply.result();
                String query = "(isDel = 0  and partyId == \"" + party.getId()
                        + "\" and readerReserveGroup == *\"barcode\": *\"" + entity.getBarcode() + "\"* )";
                CQLWrapper cql = null;
                try {
                    cql = PartyUtil.getCQL(query, -1, -1, "reserve");
                } catch (FieldException e) {
                    e.printStackTrace();
                }

                pg.get("reserve", ReserveGroup.class, cql, false, false, replyReserve -> {

                    if (replyReserve.succeeded()) {

                        List<ReserveGroup> reserveGroup = replyReserve.result().getResults();
                        ReserveGroup reserve = reserveGroup.get(0);
                        response.setReaderReserveGroup(reserve.getReaderReserveGroup());
                        response.setPartyName(reserve.getPartyName());
                        response.setVenue(party.getVenue());
                        response.setPartyStartDate(reserve.getPartyStartDate());
                        response.setPartyEndDate(reserve.getPartyEndDate());


                        CQLWrapper finalCql = null;
                        try {
                            String query2 = "(isDel = 0 and partyId == \"" + party.getId() +"\""+ " and reserveId == \""+reserve.getId()
                                    + "\" and readerReserveGroup == *\"barcode\": *\"" + entity.getBarcode() + "\"* )";
                            finalCql = PartyUtil.getCQL(query2, -1, -1, "attend");
                        } catch (FieldException e) {
                            e.printStackTrace();
                        }
                        pg.get("attend", AttendGroup.class, new String[]{"*"}, finalCql, false, false, replys -> {
                            if (replys.succeeded()) {
                                List<AttendGroup> list = replys.result().getResults();
                                AttendGroup attendResponse = null;
                                if (list.size() > 0) {
                                    attendResponse = list.get(0);
                                    Integer result = attendResponse.getAttendState();
                                    if ("3".equals(result.toString())) {
                                        future.fail("已经请假，不能再次请假");
                                        return;
                                    } else if ("1".equals(result.toString())) {
                                        future.fail("已经签到，不能再次签到");
                                        return;
                                    }

                                }


                                if ("0".equals(reserve.getStatus().toString())) {
                                    if ("1".equals(entity.getAction().toString())) {
                                        future.fail("报名未审核，不允许请假");
                                        return;
                                    }
                                    if ("2".equals(entity.getAction().toString())) {
                                        future.fail("报名未审核，不允许签到");
                                        return;
                                    }
                                }
                                Date now = new Date();
                                DateTime attendStartDate = DateUtil.parseDateTime(party.getAttendStartDate());
                                DateTime attendEndDate = DateUtil.parseDateTime(party.getAttendEndDate());
                                if (now.before(attendStartDate) && "2".equals(entity.getAction().toString())) {
                                    future.fail("未到签到时间，不允许签到");
                                    return;
                                } else if (now.after(attendEndDate) && "2".equals(entity.getAction().toString())) {
                                    future.fail("签到时间已过，不允许签到");
                                    return;
                                }
                                if ("1".equals(entity.getAction().toString())) {
                                    attend.setAttendState(3);
                                }
                                if ("2".equals(entity.getAction().toString())) {
                                    attend.setAttendState(1);
                                }
                                String attendId = UUID.randomUUID().toString();
                                attend.setReserveDate(reserve.getReserveDate());
                                attend.setId(attendId);
                                attend.setIsDel(0);
                                attend.setPartyId(party.getId());
                                attend.setPartyName(party.getPartyName());
                                    attend.setPartyStartDate(party.getPartyStartDate());
                                    attend.setPropertyName(party.getPropertyName());
                                    attend.setReaderReserveGroup(reserve.getReaderReserveGroup());
                                    attend.setState(1);
                                    attend.setReserveId(reserve.getId());

                                    Metadata metadata = reserve.getMetadata();
                                    metadata.setUpdatedDate(new Date());
                                    metadata.setCreatedDate(new Date());
                                    attend.setAttendDate(DateUtil.now());
                                    attend.setMetadata(metadata);
                                if (attendResponse != null) {
                                    attendResponse.setAttendState(attend.getAttendState());
                                    pg.update("attend", attendResponse, attendResponse.getId(), replyUpdate -> {
                                        if (replyUpdate.succeeded()) {
                                            successMap(entity, future, response);

                                        } else {
                                            errMap(entity, future);
                                            return;
                                        }
                                    });

                                   }else{
                                        pg.save("attend", attend, replySave -> {
                                            if (replySave.succeeded()) {
                                                successMap(entity, future, response);
                                            } else {
                                                errMap(entity, future);
                                                return;
                                            }
                                        });
                                  }

                            }
                        });
                    } else {

                        future.fail("未报名该活动，不允许签到");
                        return;
                    }

                });


            } else {

                future.fail("找不到这个活动，请联系管理员");
                return;

            }
        });
        future.setHandler(reply -> {
            if (reply.succeeded()) {
                asyncResultHandler.handle(Future.succeededFuture(reply.result()));
            } else {
                response.setBarcode(entity.getBarcode());
                response.setCode("err");
                response.setMsg(reply.cause().getMessage());
                response.setState(false);
                asyncResultHandler.handle(Future.failedFuture(reply.cause().getMessage()));
            }
        });
    }

    private static void errMap(ReaderReserveChangeRequest entity, Future<ReaderReserveChangeResponse> future) {
        if (entity.getAction().toString().equals("1")) {
            future.fail("读者证号：【" + entity.getBarcode() + "】请假失败");
        } else {
            future.fail("读者证号：【" + entity.getBarcode() + "】签到失败");
        }
        future.fail("操作失败！");
    }

    private static void successMap(ReaderReserveChangeRequest entity, Future<ReaderReserveChangeResponse> future, ReaderReserveChangeResponse response) {
        response.setBarcode(entity.getBarcode());
        response.setCode("success");
        if (entity.getAction().toString().equals("1")) {
            response.setMsg("读者证号：【" + entity.getBarcode() + "】请假成功");
        } else {
            response.setMsg("读者证号：【" + entity.getBarcode() + "】签到成功");

        }
        response.setState(true);
        future.complete(response);
    }
}
